const resultStatus = {
  PENDING: 'pending',
  FULFILLED: 'fulfilled',
  REJECTED: 'rejected',
};
// 简单模拟微任务
const microTask = (fn) => {
  // 判断node环境
  if (process && process.nextTick) {
    process.nextTick(fn);
  } else if (MutationObserver) {
    const p = document.createElement('p');
    const observer = new MutationObserver(fn);
    observer.observe(p, { childList: true });
    p.innerHTML = '1';
  } else {
    setTimeout(fn, 0);
  }
};
const isPromise = (obj) => {
  return !!(obj && typeof obj === 'object' && typeof obj.then === 'function');
};

class MyPromise {
  // 设置promise状态
  status = resultStatus.PENDING;
  // 收集回调函数
  handlers = [];
  // 存放结果
  value = null;

  constructor(executor) {
    try {
      // 立即执行函数
      executor(this.resolve.bind(this), this.reject.bind(this));
    } catch (err) {
      this.reject(err);
    }
  }
  changeStatus(status, value) {
    if (this.status !== resultStatus.PENDING) {
      return;
    }
    this.status = status;
    this.value = value;
    this.runHandler();
  }

  // 实现resolve
  resolve(value) {
    this.changeStatus(resultStatus.FULFILLED, value);
  }
  reject(reason) {
    this.changeStatus(resultStatus.REJECTED, reason);
  }

  // 加入队列
  pushHandler(executor, state, resolve, reject) {
    this.handlers.push({ executor, state, resolve, reject });
  }
  runHandler() {
    if (this.status === resultStatus.PENDING) {
      return;
    }
    while (this.handlers[0]) {
      const handler = this.handlers[0];
      this.runOneHandler(handler);
      this.handlers.shift();
    }
  }
  runOneHandler({ executor, state, resolve, reject }) {
    microTask(() => {
      if (this.status !== state) return;
      if (typeof executor !== 'function') {
        this.status === resultStatus.FULFILLED
          ? handler.resolve(this.value)
          : handler.reject(this.value);
        return;
      }
      try {
        const result = executor(this.value);
        if (isPromise(result)) {
          result.then(resolve, reject);
        } else {
          resolve(result);
        }
      } catch (err) {
        reject(err);
      }
    });
  }
  then(onFulfilled, onRejected) {
    return new MyPromise((resolve, reject) => {
      this.pushHandler(onFulfilled, resultStatus.FULFILLED, resolve, reject);
      this.pushHandler(onRejected, resultStatus.REJECTED, resolve, reject);
      this.runHandler();
    });
  }

  static resolve(value) {
    if (value instanceof MyPromise) {
      return value;
    }
    return new MyPromise((resolve, reject) => {
      if (value && value.then && typeof value.then === 'function') {
        microTask(() => {
          value.then(resolve, reject);
        });
        return;
      }
      resolve(value);
    });
  }
  static reject(reason) {
    return new MyPromise((_, reject) => {
      reject(reason);
    });
  }
  //promises数组里所有promise状态变为fulfilled的时候，返回的promise状态才会变为fulfilled:
  static all(promises) {
    return new MyPromise((resolve, reject) => {
      // 总共结果
      let results = [];
      let resolveLength = 0;
      if (promises.length === 0) {
        return resolve(results);
      }
      promises.forEach((promise, index) => {
        MyPromise.resolve(promise).then(
          (res) => {
            results[index] = res;
            resolveLength += 1;
            if (resolveLength === promises.length) {
              resolve(results);
            }
          },
          (err) => {
            reject(err);
          },
        );
      });
    });
  }
  //只要有一个promise的状态改变，那么返回的promise状态就会改变：
  static race(promises) {
    return new MyPromise((resolve, reject) => {
      if (promises.length === 0) {
        return;
      }
      promises.forEach((promise) => {
        MyPromise.resolve(promise).then(resolve, reject);
      });
    });
  }
  //只要有一个promise状态为fulfilled，那么返回的promise状态就为fulfilled，否则为rejected。
  static any(promises) {
    return new MyPromise((resolve, reject) => {
      let rejectLength = 0;
      let errors = [];
      if (promises.length === 0) {
        return reject(errors);
      }
      promises.forEach((promise, index) => {
        MyPromise.resolve(promise).then(resolve, (err) => {
          rejectLength += 1;
          errors[index] = err;
          if (rejectLength === promises.length) {
            reject(errors);
          }
        });
      });
    });
  }
  //不管promise状态是怎样，只有所有promise状态都不为pending的时候，
  //返回的promise状态才会改变为fulfilled。
  static allSettled(promises) {
    return new MyPromise((resolve, reject) => {
      let resolveLength = 0;
      let results = [];
      if (promises.length === 0) {
        return resolve(results);
      }
      const handleValue = (value, index) => {
        results[index] = value;
        resolveLength += 1;
        if (resolveLength === promises.length) {
          resolve(results);
        }
      };
      promises.forEach((promise, index) => {
        MyPromise.resolve(promise).then(
          (value) => {
            handleValue(value, index);
          },
          (err) => {
            handleValue(err, index);
          },
        );
      });
    });
  }
}

const pro = new MyPromise((resolve, reject) => {
  resolve(1);
});
const pro1 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve(2);
  }, 1000);
});
// const pro = MyPromise.reject(1).then(res=>console.log(res),err=>console.log(';;;',err))
setTimeout(() => {
  const pp = MyPromise.race([pro, pro1]).then((res) => {
    console.log(res);
  });
  console.log(pp);
}, 2000);

Promise.prototype.isAll = (proms) => {
  return new Promise((resolve, reject) => {
    const result = [];
    if (proms.length === 0) return resolve(result);
    proms.forEach((prom) => {
      Promise.resolve(prom).then((res, index) => {
        result[index] = res;
        if (result.length === proms.length) {
          resolve(result);
        }
      });
    });
  });
};
